package cn.buk.tms.hotel.service;

import cn.buk.api.hotel.dto.OrderDetailInfo;
import cn.buk.api.hotel.dto.PersonInfo;
import cn.buk.api.hotel.request.HotelAvailRequest;
import cn.buk.api.hotel.request.OrderPassenger;
import cn.buk.api.hotel.response.OrderCancelApiResponse;
import cn.buk.api.hotel.response.OrderCreateApiResponse;
import cn.buk.api.hotel.response.RoomPrice;
import cn.buk.common.JsonResult;
import cn.buk.common.dto.CommonDto;
import cn.buk.common.util.DateUtil;
import cn.buk.common.util.HttpUtil;
import cn.buk.qms.service.BaseOrderService;
import cn.buk.tms.common.constant.TmsOrderConstant;
import cn.buk.tms.dto.CityDto;
import cn.buk.tms.dto.LoginInfoDto;
import cn.buk.tms.dto.request.HotelOrderRequestDto;
import cn.buk.tms.dto.response.HotelOrderResponseDto;
import cn.buk.tms.entity.bill.BillInfo;
import cn.buk.tms.entity.config.EnterpriseConfig;
import cn.buk.tms.entity.misc.*;
import cn.buk.tms.entity.order.OrderNoInfo;
import cn.buk.tms.entity.order.hotel.HotelOrder;
import cn.buk.tms.entity.order.hotel.HotelOrderPassenger;
import cn.buk.tms.entity.order.hotel.HotelOrderPrice;
import cn.buk.tms.hotel.dao.HotelOrderDao;
import cn.buk.tms.hotel.dto.HotelAvailDto;
import cn.buk.tms.hotel.dto.HotelInfoDto;
import cn.buk.tms.hotel.dto.HotelOrderPassengerDto;
import cn.buk.tms.hotel.dto.HotelRoomPriceDto;
import cn.buk.tms.hotel.request.SupplierHotelOrderCreate;
import cn.buk.tms.hotel.sc.HotelOrderSearchCriteria;
import cn.buk.tms.util.HotelOrderUtil;
import cn.buk.tms.util.ValidationUtils;
import com.alibaba.fastjson.JSON;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Component;

import jakarta.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static cn.buk.common.Constant.DATE_YYYY_MM_DD;
import static cn.buk.tms.common.constant.TmsConstant.TRAVEL_ZONE_THIRD_CLASS;

/**
 * @author yfdai
 */
@Component
public class HotelOrderServiceImpl extends BaseOrderService implements HotelOrderService {

    private static final Logger logger = LogManager.getLogger(HotelOrderServiceImpl.class);

    @Value("${api_hotel_url}")
    private String apiUrl;



    @Autowired
    private HotelOrderDao hotelOrderDao;

    /**
     * 搜索订单
     */
    @Override
    public List<HotelOrderResponseDto> searchHotelOrders(final int enterpriseId, final int userId, HotelOrderSearchCriteria sc) {
        List<Integer> allowedCustomerIds = searchAllowedCustomerIds(enterpriseId, userId);

        if (isOnlySeeOwn(enterpriseId, userId)) {
            //只能看自己的订单
            sc.setOp1(userDao.getUserById(userId).getUsername());
        }

        List<HotelOrder> orders = hotelOrderDao.searchHotelOrders(enterpriseId, sc, allowedCustomerIds);

        final boolean needHideCustomerName = isNeedHideCustomerName(enterpriseId, userId);
        User user = userDao.getUserById(userId);

        List<HotelOrderResponseDto> dtos = new ArrayList<>();
        for (HotelOrder order : orders) {
            maskCustomerName(order.getCustomer(), order.getOperator(), user.getUsername(), needHideCustomerName);
            dtos.add(HotelOrderResponseDto.createByHotelOrder(order));
        }

        return dtos;
    }

    @Override
    public CommonDto<HotelOrderResponseDto> searchHotelOrders2(final int enterpriseId, final int userId, HotelOrderSearchCriteria sc) {

        List<HotelOrderResponseDto> datas = this.searchHotelOrders(enterpriseId, userId, sc);

        CommonDto<HotelOrderResponseDto> commonDto = new CommonDto<>();
        commonDto.setDataList(datas);
        commonDto.setPage(sc.getPage());
        commonDto.setErrcode(0);

        return commonDto;
    }

    /**
     * 获取订单详情
     */
    @Override
    public HotelOrderResponseDto getHotelOrderById(final int enterpriseId, int userId, final int orderId) {
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);

        if (hotelOrder == null || hotelOrder.getEnterpriseId() != enterpriseId) {
            return null;
        }

        List<Integer> allowedCustomerIds = searchAllowedCustomerIds(enterpriseId, userId);
        if (!allowedCustomerIds.isEmpty()
                && hotelOrder.getCustomer() != null
                && !allowedCustomerIds.contains(hotelOrder.getCustomer().getId())) {
            return null;
        }

        //是否要对当前用户隐藏客户名称
        if (isNeedHideCustomerName(enterpriseId, userId)) {
            User user = userDao.getUserById(userId);
            maskCustomerName(hotelOrder.getCustomer(), hotelOrder.getOperator(), user.getUsername(), true);
        }

        return HotelOrderResponseDto.createByHotelOrder(hotelOrder);
    }

    /**
     * 创建订单
     */
    @Override
    public JsonResult createHotelOrder(final int enterpriseId, final String username, HotelOrderRequestDto dto) {
        dto.processPassengerInfo();

        try {
            ValidationUtils.validate(dto);
            for (HotelOrderPassengerDto psgDto : dto.getPassengers()) {
                ValidationUtils.validate(psgDto);
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage());
            return JsonResult.createJsonResult(-1, ex.getMessage());
        }

        if (dto.getCheckInDate().getTime() >= dto.getCheckOutDate().getTime()) {
            return JsonResult.createJsonResult(-2, "入住日期需要早于离店日期");
        }

        if (dto.getPassengers().size() < dto.getRoomCount()) {
            return JsonResult.createJsonResult(-3, "入住人数需要大于等于房间数");
        }

        if (dto.getHotelId() > 0 && dto.getLastArriveTime() != null && dto.getLastArriveTime().trim().length() < 5) {
                return JsonResult.createJsonResult(-4, "请检查最晚到店时间");

        }


        HotelOrder hotelOrder = HotelOrderUtil.convertToHotelOrder(dto);

        hotelOrder.setEnterpriseId(enterpriseId);
        hotelOrder.setOperator(username);

        // 订单号
        hotelOrder.setOrderNo(orderNoGenerator.generateOrderNo(enterpriseId, OrderNoInfo.ORDER_HOTEL));

        try {
            int retCode = hotelOrderDao.createHotelOrder(hotelOrder);
            return JsonResult.createJsonResult(retCode);
        } catch (RuntimeException ex) {
            logger.error(ex.getMessage());
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }
    }

    /**
     * 调用酒店接口检查是否可用
     */
    private JsonResult checkAvailableHotel(final int enterpriseId, final String username, HotelOrder hotelOrder) {

        HotelAvailDto rs = execCheckHotelAvail(hotelOrder);

        if (hotelOrder.getId() == 0) {
            return JsonResult.createJsonResult(rs.isStatus() ? 1 : 0, rs.getMessage());
        }

        //TODO 记录到订单日志

        if (rs.isStatus()) {
            if (rs.getMessage() != null && rs.getMessage().trim().length() > 0) {
                hotelOrderDao.appendHotelOrderHistory(enterpriseId, username, hotelOrder.getId(), "可定性检查：成功(" + rs.getMessage() + ").");
                return JsonResult.createJsonResult(1, rs.getMessage());
            } else {
                return JsonResult.createJsonResult(1);
            }
        } else {
            //用返回的价格更新本地的代理商价格
            updateHotelOrderSupplierPrice(enterpriseId, username, hotelOrder, rs);

            hotelOrderDao.appendHotelOrderHistory(enterpriseId, username, hotelOrder.getId(), "可定性检查：失败(" + rs.getCode() + ", " + rs.getMessage() + ").");

            return JsonResult.createJsonResult(-1, rs.getMessage());
        }

    }

    /**
     * 调用接口，检查酒店订单的可定性
     */
    private HotelAvailDto execCheckHotelAvail(HotelOrder hotelOrder) {
        HotelAvailRequest request = new HotelAvailRequest();

        final int supplierHotelId = doGetSupplierHotelId(hotelOrder.getHotelId());
        final int supplierRoomTypeId = doGetSupplierRoomTypeId(hotelOrder.getRoomId());
        final int supplierRoomId = doGetSupplierRoomId(hotelOrder.getRoomId());

        request.setHotelId(supplierHotelId);
        request.setRoomTypeId(supplierRoomTypeId + "");
        request.setRoomId(supplierRoomId + "");

        request.setQuantity(hotelOrder.getRoomCount());
        request.setPersons(hotelOrder.getPsgCount());
        //向供应商提交的金额是成本金额
        request.setTotalAmount(hotelOrder.getTotalCost());

//        request.getDateRange().setStart(LocalDateTime.parse(DateUtil.formatDate(hotelOrder.getCheckInDate(), DATE_YYYY_MM_DD) + "T00:00:00"));
//        request.getDateRange().setEnd(LocalDateTime.parse(DateUtil.formatDate(hotelOrder.getCheckOutDate(), DATE_YYYY_MM_DD) + "T00:00:00"));

        for (HotelOrderPrice orderPrice : hotelOrder.getPrices()) {
            RoomPrice roomPrice = new RoomPrice();

            roomPrice.setEffectiveDate(orderPrice.getEffectiveDate());
            roomPrice.setCurrency(orderPrice.getCurrency());
            if (orderPrice.getSupplierInclusiveAmount() == 0) {
                roomPrice.setInclusiveAmount(orderPrice.getInclusiveAmount());
            } else {
                roomPrice.setInclusiveAmount(orderPrice.getSupplierInclusiveAmount());
            }
            roomPrice.setMealType(orderPrice.getMealType());
            roomPrice.setMealCount(orderPrice.getMealCount());

            request.getEverydayPrices().add(roomPrice);
        }

        final String postStr = JSON.toJSONString(request);
        logger.info("request: " + postStr);

        final String url = apiUrl + "/hotel/avail";

        final String jsonStr = HttpUtil.postUrl(url, postStr, true);
        logger.info("response: " + jsonStr);

        return JSON.parseObject(jsonStr, HotelAvailDto.class);
    }

    /**
     * 通过售卖房型ID获取供应商的基础房型ID
     */
    private int doGetSupplierRoomTypeId(int roomId) {
        final String url = apiUrl + "/room/" + roomId + "/supplierRoomTypeId";
        String val = HttpUtil.getUrl(url, null);
        return Integer.parseInt(val);
    }

    /**
     * 通过售卖房型ID获取供应商的售卖房型ID
     */
    private int doGetSupplierRoomId(int roomId) {
        final String url = apiUrl + "/room/" + roomId + "/supplierRoomId";
        String val = HttpUtil.getUrl(url, null);
        return Integer.parseInt(val);
    }

    /**
     * 通过子酒店ID获取供应商的子酒店ID
     */
    private int doGetSupplierHotelId(int hotelId) {
//        /hotel/{hotelId}/supplierHotelId
        final String url = apiUrl + "/hotel/" + hotelId + "/supplierHotelId";
        logger.warn(url);
        String val = HttpUtil.getUrl(url, null);

        return Integer.parseInt(val);
    }

    /**
     * 通过酒店ID获取所在城市的信息
     */
    private CityDto doGetCityIdByHotelId(int hotelId) {
//        /hotel/{hotelId}/city
        if (hotelId < 1) {
            return null;
        }
        final String url = apiUrl + "/hotel/" + hotelId + "/city";
        logger.info(url);
        String val = HttpUtil.getUrl(url, null);

        return JSON.parseObject(val, CityDto.class);
    }

    private HotelInfoDto doGetHotelInfoByHotelId(int hotelId) {
        if (hotelId < 1) {
            return null;
        }
        final String url = apiUrl + "/hotel/" + hotelId;
        logger.info(url);
        String val = HttpUtil.getUrl(url, null);

        return JSON.parseObject(val, HotelInfoDto.class);
    }

    /**
     * 修改酒店订单的备注
     */
    @Override
    public JsonResult updateHotelOrderRemark(int enterpriseId, String username, int orderId, String remark) {
        try {
            int retCode = hotelOrderDao.updateHotelOrderRemark(enterpriseId, username, orderId, remark);
            return JsonResult.createJsonResult(retCode);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }
    }

    /**
     * 修改酒店订单的供应商
     */
    @Override
    public JsonResult updateHotelOrderSupplier(int enterpriseId, String username, int orderId, int supplierId) {
        try {
            int retCode = hotelOrderDao.updateHotelOrderSupplier(enterpriseId, username, orderId, supplierId);
            return JsonResult.createJsonResult(retCode);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }
    }

    /**
     * 修改酒店订单的支付方式
     */
    @Override
    public JsonResult updateHotelOrderPaymentMethod(int enterpriseId, String username, int orderId, int paymentMethodId) {
        try {
            int retCode = hotelOrderDao.updateHotelOrderPaymentMethod(enterpriseId, username, orderId, paymentMethodId);
            return JsonResult.createJsonResult(retCode);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }
    }

    /**
     * 修改酒店订单的价格
     */
    @Override
    public JsonResult updateHotelOrderPrice(int enterpriseId, String username, int orderId, double price, double cost, double serviceCharge) {
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);
        if (hotelOrder.getStatus() == TmsOrderConstant.HOTEL_ORDER_STATUS_DONE
                || hotelOrder.getStatus() == TmsOrderConstant.HOTEL_ORDER_STATUS_CANCELED) {
            return JsonResult.createJsonResult(-1, "价格已不能修改");
        }

        var dto = HotelOrderUtil.convertToHotelOrderRequestDto(hotelOrder);
        dto.setPrice(price);
        dto.setBottomPrice(cost);
        dto.setServiceCharge(serviceCharge);
        dto.calc();

        int retCode = hotelOrderDao.updateHotelOrderPrice(enterpriseId, username, orderId, price, cost, serviceCharge,
                dto.getTotalAmount(), dto.getTotalCost(), dto.getProfit());
        return JsonResult.createJsonResult(retCode);
    }

    @Override
    @Transactional
    public JsonResult submitHotelOrder(int enterpriseId, String username, int orderId) {
        try {
            int retCode = hotelOrderDao.submitHotelOrder(enterpriseId, username, orderId);
            if (retCode == 1) {
                //如果该公司不需要审核，则默认审核通过
                HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);
                boolean needBeAudited = hotelOrder.getCustomerType() == 1
                        && hotelOrder.getCustomer().getApprovalTicket() == 1;
                if (!needBeAudited) {
                    hotelOrderDao.approveHotelOrder(enterpriseId, username, orderId, 0, "默认审批通过");
                }
            }
            return JsonResult.createJsonResult(retCode);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }
    }

    @Override
    public JsonResult approveHotelOrder(int enterpriseId, String username, int orderId, int denyCode, String denyReason) {
        if (denyCode != 0 && (denyReason == null || denyReason.trim().length() < 3)) {
            return JsonResult.createJsonResult(-1, "请输入拒绝的原因");
        }
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);
        if (enterpriseId != hotelOrder.getEnterpriseId()) {
            return JsonResult.createJsonResult(-2, "订单不存在");
        }


        int retCode = hotelOrderDao.approveHotelOrder(enterpriseId, username, orderId, denyCode, denyReason);

        return JsonResult.createJsonResult(retCode);
    }

    /**
     * 开始处理订单
     */
    @Override
    public JsonResult processHotelOrder(final int enterpriseId, String username, final int orderId) {
        //核对信用额度是否足够
        HotelOrder orderInfo = hotelOrderDao.getHotelOrderById(orderId);
        if (orderInfo == null || orderInfo.getEnterpriseId() != enterpriseId) {
            return JsonResult.createJsonResult(-404, "不存在");
        }

        if (orderInfo.getCustomer() != null && orderInfo.getCustomer().getCustomerEnterpriseId() >0) {
            //该客户可以判断授信额度
            final double totalAmount = orderInfo.getTotalAmount();
            final int customerEnterpriseId = orderInfo.getCustomer().getCustomerEnterpriseId();
            if (isOverCreditLimit(enterpriseId, customerEnterpriseId, totalAmount)) {
                return JsonResult.createJsonResult(-100, "订单金额(" + totalAmount + ")大于可用额度");
            }
        }

        try {
            int retCode = hotelOrderDao.processHotelOrder(enterpriseId, username, orderId);
            return JsonResult.createJsonResult(retCode);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }
    }

    /**
     * 酒店订单处理完毕
     * 如果有酒店id, 则默认走供应商API渠道
     */
    @Override
    public JsonResult finishHotelOrder(int enterpriseId, String username, int orderId, String confirmNo) {

        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);
        if (hotelOrder.getSupplier() == null || hotelOrder.getPaymentMethod() == null) {
            return JsonResult.createJsonResult(-1, "供应商、支付方式需要设置");
        }

        //判断是否走供应商渠道，如果走的话，需要供应商渠道的订单状态
        if (hotelOrder.getReservationChannel() == null || hotelOrder.getReservationChannel() == 1) {
            //未指定预订渠道，或渠道为携程代理通
            if (hotelOrder.getHotelId() > 0 && hotelOrder.getSupplierOrderStatus() != 4) {
                    return JsonResult.createJsonResult(-2, "供应商订单状态未完成");

            }
        }

        int retCode = 0;
        try {
            retCode = hotelOrderDao.finishHotelOrder(enterpriseId, username, orderId, confirmNo);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }

        if (retCode == 1) {
            try {
                importService.importHotelOrder(enterpriseId, username, orderId);
            } catch (Exception ex) {
                //TODO 发送提醒短信给管理员
            }
        }

        if (retCode == 1) {
            //TODO 发送预订完成短信
            this.sendHotelOrderFinishedAlert(enterpriseId, username, orderId);
        }

        return JsonResult.createJsonResult(retCode);
    }

    /**
     * 发送酒店预订完成短信
     */
    private void sendHotelOrderFinishedAlert(final int enterpriseId, final String username, final int orderId) {
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);
        //入住人和联系人都发
        doSendHotelOrderLinkmanSms(enterpriseId, username, hotelOrder);
        doSendHotelOrderPassengerSms(enterpriseId, username, hotelOrder);
    }

    private void doSendHotelOrderLinkmanSms(final int enterpriseId, final String username, HotelOrder hotelOrder) {
        if (hotelOrder.getContactPhone() == null || hotelOrder.getContactPhone().trim().length() != 11) {
            logger.error("HotelOrder's contact phone is not correct.");
            return;
        }

        String smsContent = generateHotelOrderSmsContent(enterpriseId, hotelOrder, 0);

        SmsDetail smsDetail = SmsDetail.createSmsDetail(enterpriseId, username, hotelOrder.getContactPhone(), smsContent, hotelOrder.getOrderNo() );

        sendSms(smsDetail);
    }

    private void doSendHotelOrderPassengerSms(final int enterpriseId, final String username, HotelOrder hotelOrder) {
        for(HotelOrderPassenger psg: hotelOrder.getPassengers()) {
            if (psg.getMobile() == null || psg.getMobile().trim().length() != 11) {
                continue;
            }

            String smsContent = generateHotelOrderSmsContent(enterpriseId, hotelOrder, psg.getId());
            SmsDetail smsDetail = SmsDetail.createSmsDetail(enterpriseId, username, psg.getMobile(), smsContent, hotelOrder.getOrderNo());
            sendSms(smsDetail);
        }
    }

    private String generateHotelOrderSmsContent(final int enterpriseId, final HotelOrder hotelOrder, final int psgId) {
        String psgName = null;
        if (psgId == 0) {
            for (HotelOrderPassenger psg : hotelOrder.getPassengers()) {
                if (psgName == null) {
                    psgName = psg.getName().trim();
                } else {
                    psgName += ", " + psg.getName().trim();
                }
            }
        } else {
            for (HotelOrderPassenger psg : hotelOrder.getPassengers()) {
                if (psg.getId() == psgId) {
                    psgName = psg.getName();
                }
            }
        }

        if (psgName == null) {
            throw new RuntimeException("Passenger name should not be null.");
        }

//        {{王振华 2020年5月22日入住怡莱酒店高级大床房，1间1晚，含单早}}
        String orderContent = psgName + " " + DateUtil.formatDate(hotelOrder.getCheckInDate(), "yyyy年MM月dd日");
        orderContent += "入住" + hotelOrder.getHotelName() + "(" + hotelOrder.getRoomType() + ")，";
        orderContent += hotelOrder.getRoomCount() + "间" + hotelOrder.getCount() / hotelOrder.getRoomCount() + "晚";
        //查看每间夜是否含早, 暂时只看第一天
        for (HotelOrderPrice orderPrice : hotelOrder.getPrices()) {
            if (orderPrice.getMealType() == 1 && orderPrice.getMealCount() > 0) {
                orderContent += "，含" + orderPrice.getMealCount() + "份早餐";
            } else {
                orderContent += "，不含早";
            }
            break;
        }
//        orderContent += "。";

        final String companySign = doGetEntCfg(enterpriseId, EnterpriseConfig.API_SMS_COMPANY_SIGN);

        final String bookingRule = "订单不可取消修改";
        final String hotelAddress = hotelOrder.getHotelAddress() == null ? "无" : hotelOrder.getHotelAddress().trim();

        final String smsTemplate = "%s酒店预订成功：%s。确认号：%s。%s。酒店地址：%s。";

        return String.format(smsTemplate,
                companySign,
                orderContent,
                hotelOrder.getSupplierConfirmNo(),
                bookingRule,
                hotelAddress);
    }

    @Override
    public List<OperationLog> searchHotelOrderHistory(int enterpriseId, int orderId) {
        return hotelOrderDao.searchHotelOrderHistory(enterpriseId, orderId);
    }

    /**
     * 取消酒店订单
     */
    @Override
    public JsonResult cancelHotelOrder(int enterpriseId, String username, int orderId, String remark) {
        //TODO 需要判断订单是否需要退款
        try {
            int retCode = hotelOrderDao.cancelHotelOrder(enterpriseId, username, orderId, remark);
            return JsonResult.createJsonResult(retCode);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-100, ex.getMessage());
        }
    }

    /**
     * 回滚酒店订单的状态
     */
    @Override
    @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_SUPERVISOR})
    public JsonResult rollbackHotelOrder(final int enterpriseId, final String username, final int orderId, final String remark) {
        if (remark == null || remark.trim().length() < 2) {
            return JsonResult.createJsonResult(-10, "请输入理由");
        }

        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);
        if (hotelOrder == null || hotelOrder.getEnterpriseId() != enterpriseId) {
            return JsonResult.createJsonResult(-1, "订单不存在");
        }

        if (hotelOrder.getStatus() != TmsOrderConstant.HOTEL_ORDER_STATUS_DONE) {
            return JsonResult.createJsonResult(-2, "订单状态不是完成状态。");
        }

        List<BillInfo> billInfos = billService.searchBillInfoByOrderNo(enterpriseId, hotelOrder.getOrderNo());
        if (billInfos.size() > 0) {
            doSendAlert(enterpriseId, "酒店订单(" + hotelOrder.getOrderNo() + ")回滚失败，存在对应的账单", null, EntDepartment.DEPT_ADMINISTRATOR);
            return JsonResult.createJsonResult(-2, "存在对应的账单，不能回滚");
        }

        int retCode = hotelOrderDao.rollbackHotelOrder(enterpriseId, username, orderId, remark);
        if (retCode > 0) {
            doSendAlert(enterpriseId, "酒店订单(" + hotelOrder.getOrderNo() + ")已回滚: " + remark, null, EntDepartment.DEPT_ADMINISTRATOR);
        }

        return JsonResult.createJsonResult(retCode);
    }

    /**
     * 自动统计酒店订单的状态
     */
    @Override
    public void autoAlertHotelOrderStatus() {
        final int enterpriseId = 5;
        HotelOrderSearchCriteria sc = new HotelOrderSearchCriteria();
        sc.setStatus(0);
        sc.setPageSize(1000);

        List<HotelOrder> orders = hotelOrderDao.searchHotelOrders(enterpriseId, sc, null);

        if (orders.size() > 0) {
            doSendAlert(enterpriseId, "有" + orders.size() + "个酒店订单待处理", null, EntDepartment.DEPT_TICKETING);
        }
    }

    @Override
    public JsonResult checkSupplierHotelAvail(int enterpriseId, String username, int orderId) {
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);

        if (hotelOrder.getReservationChannel() != null && hotelOrder.getReservationChannel() != 1) {
            return JsonResult.createJsonResult(-1, "预订渠道非代理通");
        }

        return checkAvailableHotel(enterpriseId, username, hotelOrder);
    }

    @Override
    public JsonResult syncSupplierHotelOrder(int enterpriseId, String username, int orderId) {
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);

        final int supplierHotelId = doGetSupplierHotelId(hotelOrder.getHotelId());

        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("orderNo", hotelOrder.getOrderNo()));
        params.add(new BasicNameValuePair("supplierHotelId", supplierHotelId + ""));

        final String url = apiUrl + "/hotel/order?";
        final String jsonStr = HttpUtil.getUrl(url, params);

        OrderDetailInfo rs = JSON.parseObject(jsonStr, OrderDetailInfo.class);

        if (rs.getDistributorOrderId() == null) {
            return JsonResult.createJsonResult(-1, "代理通无此订单");
        } else if (rs.getDistributorOrderId().equalsIgnoreCase(hotelOrder.getOrderNo())) {
            //订单获取成功
            int retCode = doCompareHotelOrderInfo(hotelOrder, rs);
            if (retCode <= 0) {
                return JsonResult.createJsonResult(-3, "订单内容有差异");
            } else {
                if (rs.getOrderStatus() != hotelOrder.getSupplierOrderStatus()) {
                    //供应商订单状态变化
//                    orderDetailInfo	订单状态	orderStatus	int	是
//                    orderDetailInfo	订单确认方式	orderConfirmType	int	否
//                    1：按入住人入住
//                    2：按确认号入住
//                    orderDetailInfo	订单确认号	orderConfirmNo	String	否
//                    orderDetailInfo	订单拒绝类型	orderRejectType	int	否
//                    1：满房
//                    2：房价不对
//                    3：其他原因
//                    orderDetailInfo	订单其它拒绝原因	orderRejectReason	String	否
//                    orderDetailInfo	备注	remark	string	否

                    try {
                        int retCode1 = hotelOrderDao.updateHotelOrderSupplierOrderStatus(enterpriseId, username,
                                hotelOrder.getId(), rs.getOrderId(), rs.getOrderStatus(),
                                rs.getOrderConfirmType(), rs.getOrderConfirmNo(),
                                rs.getOrderRejectType(), rs.getOrderRejectReason(),
                                rs.getRemark());
                        if (retCode1 > 0) {
                            doSendAlert(enterpriseId, "酒店订单状态同步成功：" + hotelOrder.getOrderNo() + ", " + HotelOrder.getSupplierOrderStatusDesc(rs.getOrderStatus()), null, EntDepartment.DEPT_ADMINISTRATOR);
                        }
                    } catch (RuntimeException ex) {
                        logger.error(ex.getMessage());
                        doSendAlert(enterpriseId, "酒店订单状态同步失败：" + orderId + ", " + ex.getMessage(), null, EntDepartment.DEPT_ADMINISTRATOR);
                    }
                }

                return JsonResult.createJsonResult(1, "代理通订单详情获取成功");
            }
        } else {
            return JsonResult.createJsonResult(-2, "调试中...");
        }
    }

    /**
     * 比较本地酒店订单和代理通接口返回的订单内容差异
     */
    private int doCompareHotelOrderInfo(final HotelOrder hotelOrder, final OrderDetailInfo rs) {
        //本地订单号
        if (!hotelOrder.getOrderNo().equalsIgnoreCase(rs.getDistributorOrderId())) {
            return -1;
        }

        //房间数量
        if (hotelOrder.getRoomCount() != rs.getQuantity()) {
            return -10;
        }

        //房型id
        final String supplierRoomId = doGetSupplierRoomId(hotelOrder.getRoomId()) + "";
        if (!supplierRoomId.equalsIgnoreCase(rs.getRoomId())) {
            return -11;
        }

        //入住人数
        if (hotelOrder.getPsgCount() != rs.getPersonCount()) {
            return -12;
        }

        //入住人姓名
        for (HotelOrderPassenger psg : hotelOrder.getPassengers()) {
            boolean existed = false;
            for (PersonInfo personInfo : rs.getPersons()) {
                if (personInfo.getName().equalsIgnoreCase(psg.getName())) {
                    existed = true;
                    break;
                }
            }

            if (!existed) {
                logger.error(psg.getId() + ": " + psg.getName());
                return -13;
            }
        }

        //TODO 联系人、联系方式的比较 2020-1-24

        //入住、离店日期
        final String checkInDate0 = DateUtil.formatDate(hotelOrder.getCheckInDate(), DATE_YYYY_MM_DD);
        final String checkInDate1 = rs.getDateRange().getStart().toString();
        if (!checkInDate0.equalsIgnoreCase(checkInDate1)) {
            logger.error(checkInDate0 + ", " + checkInDate1);
            return -14;
        }
        final String checkOutDate0 = DateUtil.formatDate(hotelOrder.getCheckOutDate(), DATE_YYYY_MM_DD);
        final String checkOutDate1 = rs.getDateRange().getEnd().toString();
        if (!checkOutDate0.equalsIgnoreCase(checkOutDate1)) {
            logger.error(checkOutDate0 + ", " + checkOutDate1);
            return -15;
        }

        //总价
        if (Math.abs(hotelOrder.getTotalCost() - rs.getTotalAmount().getAmount()) >= 0.0001) {
            return -16;
        }

        return 1;
    }

    @Override
    public JsonResult cancelSupplierHotelOrder(int enterpriseId, String username, int orderId) {
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);

        if (hotelOrder.getSupplierOrderNo() == null || hotelOrder.getSupplierOrderNo().trim().length() == 0) {
            return JsonResult.createJsonResult(-1, "订单中没有供应商的订单号.");
        }

        final int supplierHotelId = doGetSupplierHotelId(hotelOrder.getHotelId());

//      String body = "orderNo=" + hotelOrder.getSupplierOrderNo() + "&supplierHotelId=" + supplierHotelId;
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("orderNo", hotelOrder.getSupplierOrderNo()));
        params.add(new BasicNameValuePair("supplierHotelId", supplierHotelId + ""));

        final String url = apiUrl + "/hotel/cancelOrder";
        final String jsonStr = HttpUtil.postUrl(url, params);

        OrderCancelApiResponse rs = JSON.parseObject(jsonStr, OrderCancelApiResponse.class);

        if (rs.getStatus() == -1) {
            return JsonResult.createJsonResult(-1, "取消失败：代理通无此订单");
        } else if (rs.getStatus() == 0) {
            //订单获取成功
            return JsonResult.createJsonResult(1, "订单取消中，请查询订单状态");
        } else if (rs.getStatus() == 1) {
            //订单获取成功
            return JsonResult.createJsonResult(-2, "取消订单失败");
        } else if (rs.getStatus() == 2) {
            //订单获取成功
            return JsonResult.createJsonResult(-3, "订单ID不存在");
        } else if (rs.getStatus() == 3) {
            //订单获取成功
            return JsonResult.createJsonResult(-4, "订单已取消");
        } else {
            return JsonResult.createJsonResult(-5, "调试中...");
        }
    }

    @Override
    public JsonResult createSupplierHotelOrder(final int enterpriseId, final String username, final int orderId) {
        HotelOrder hotelOrder = hotelOrderDao.getHotelOrderById(orderId);

        if (hotelOrder.getReservationChannel() != null && hotelOrder.getReservationChannel() != 1) {
            return JsonResult.createJsonResult(-1, "预订渠道非代理通");
        }

        SupplierHotelOrderCreate request = new SupplierHotelOrderCreate();

        request.setHotelId(doGetSupplierHotelId(hotelOrder.getHotelId()));
        request.setRoomId(doGetSupplierRoomId(hotelOrder.getRoomId()) + "");

        request.setTotalAmount(hotelOrder.getTotalCost());
        //TODO 此处以后修改，按照订单中的货币类型 yfdai 2020-1-24
        request.setCurrency("CNY");

        request.setCheckInDate(DateUtil.formatDate(hotelOrder.getCheckInDate(), DATE_YYYY_MM_DD));
        request.setCheckOutDate(DateUtil.formatDate(hotelOrder.getCheckOutDate(), DATE_YYYY_MM_DD));

        request.setQuantity(hotelOrder.getRoomCount());

        for (HotelOrderPrice priceInfo : hotelOrder.getPrices()) {
            HotelRoomPriceDto roomPrice = new HotelRoomPriceDto();

            roomPrice.setEffectiveDate(priceInfo.getEffectiveDate());
            roomPrice.setInclusiveAmount(priceInfo.getInclusiveAmount());
            roomPrice.setCurrency("CNY");
            roomPrice.setMealType(priceInfo.getMealType());
            roomPrice.setMealCount(priceInfo.getMealCount());

            request.getEverydayPrices().add(roomPrice);
        }

        for (HotelOrderPassenger psg : hotelOrder.getPassengers()) {

            OrderPassenger op = new OrderPassenger();
            op.setName(psg.getName());

            request.getPersons().add(op);
        }

        request.setDistributorOrderId(hotelOrder.getOrderNo());
        request.setOrderDate(DateUtil.formatDate(DateUtil.getCurDate(), DATE_YYYY_MM_DD));

        request.setLinkman(hotelOrder.getLinkman());
        request.setContactPhone(hotelOrder.getContactPhone());

        final String postStr = JSON.toJSONString(request);
        final String url = apiUrl + "/hotel/order";
        final String jsonStr = HttpUtil.postUrl(url, postStr, true);

        OrderCreateApiResponse rs = null;
        try {
            rs = JSON.parseObject(jsonStr, OrderCreateApiResponse.class);
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }

        if (rs == null) {
            return JsonResult.createJsonResult(-100, "接口调用失败");
        }

        if (rs.getOrderInfo() == null) {
            if (rs.getMessage() != null) {
                return JsonResult.createJsonResult(-1, rs.getMessage().getMessage());
            } else {
                return JsonResult.createJsonResult(-1);
            }
        } else {
            //创建成功, 同步订单详情信息
            syncSupplierHotelOrder(enterpriseId, username, orderId);

            return JsonResult.createJsonResult(1, rs.getOrderInfo().getOrderId());
        }
    }

    @Override
    public void checkHotelOrderNeedApprover(final int ownerId, String agentName) {
        List<HotelOrder> hotelOrders = hotelOrderDao.searchNeedAssignApproverHotelOrders(ownerId);
        for (HotelOrder o : hotelOrders) {
            //根据订单提交的用户名来判断
            User user = userDao.getUserByUsername(o.getOperator());
            //判断是否为下级企业客户自助提交的订单
            if (user == null || user.getParentEnterprise() != ownerId) {
                continue;
            }

            final User mainUser = userDao.getUserById(user.getEnterpriseId());
            final int customerId = o.getCustomer().getId();

            String approver = doAssignOrderApprover(ownerId, user, mainUser, customerId);
            if (approver != null) {
                assignApproverHotelOrder(ownerId, agentName, o.getId(), approver);
                //发送酒店订单的审批提醒
                sendHotelOrderApproveAlert(ownerId, o.getOrderNo(), approver);
            }
        }
    }

    /**
     * 发送酒店订单的审批提醒
     */
    private void sendHotelOrderApproveAlert(int ownerId, String orderNo, String approver) {
        LoginInfoDto loginInfoDto = getCustomerEmployeeLoginInfo(approver, null);
        String mobile = loginInfoDto.getMobile();
        String smsContent =
                "短信内容:酒店订单(" + orderNo + ")需要审批，通知指定审批人(" + approver + ").";
        String email = loginInfoDto.getEmail();
        String emailSubject = "酒店订单(" + orderNo + ")等待审批";
        String emailBody = "酒店订单审批邮件发送内容";
        doSendAlertApprove(ownerId, mobile, smsContent, email, emailSubject, emailBody);
    }

    @Override
    public void checkHotelOrderPrice(final int enterpriseId, String agentName) {
        //查找需要验价的订单，30分钟内的订单
        final Date startDate = DateUtil.addDays(DateUtil.getCurDate(), -1);
        List<HotelOrder> hotelOrders = hotelOrderDao.searchNeedPriceCheckHotelOrders(enterpriseId, startDate);

        for (HotelOrder o : hotelOrders) {
            if (o.getPriceChecked() != 0) {
                continue;
            }


            //只针对客户自助提交的酒店订单
            User user = userDao.getUserByUsername(o.getOperator());
            //判断是否为下级企业客户自助提交的订单
            if (user == null || user.getParentEnterprise() != enterpriseId) {
                continue;
            }

            HotelAvailDto hotelAvailDto = execCheckHotelAvail(o);
            if (!hotelAvailDto.isStatus()) {
                //不可订
                if (hotelAvailDto.getEverydayPrices().size() == 0) {
                    hotelOrderDao.updateHotelOrderPriceChecked(enterpriseId, o.getId(), agentName, 4, hotelAvailDto.getCode() + ": " + hotelAvailDto.getMessage());
                } else {
                    if ("1014".equalsIgnoreCase(hotelAvailDto.getCode())) {
                        //1014: 当日房态为满房
                        hotelOrderDao.updateHotelOrderPriceChecked(enterpriseId, o.getId(), agentName, 4, hotelAvailDto.getCode() + ": " + hotelAvailDto.getMessage());
                    } else {
                        hotelOrderDao.updateHotelOrderPriceChecked(enterpriseId, o.getId(), agentName, null, hotelAvailDto.getCode() + ": " + hotelAvailDto.getMessage());
                    }
                }
                //用返回的价格更新本地的代理商价格
                updateHotelOrderSupplierPrice(enterpriseId, agentName, o, hotelAvailDto);
            }
            else {
                //可定
                hotelOrderDao.updateHotelOrderPriceChecked(enterpriseId, o.getId(), agentName, 1, "可定性检查通过");
            }
        }

    }

    /**
     * 修改供应商提供的每日酒店价格
     */
    private void updateHotelOrderSupplierPrice(final int enterpriseId,
                                               final String agentName,
                                               final HotelOrder o,
                                               final HotelAvailDto hotelAvailDto) {
        int changeCount = 0;
        logger.info(hotelAvailDto.getEverydayPrices().size() + ", " + o.getPrices().size());
        if ((hotelAvailDto.getEverydayPrices().size() == o.getPrices().size())) {
            for (HotelRoomPriceDto priceDto : hotelAvailDto.getEverydayPrices()) {
                if (priceDto.getEffectiveDate() == null) {
                    logger.error(priceDto.getEffectiveDate());
                    continue;
                }
                for (HotelOrderPrice price : o.getPrices()) {
                    if (price.getEffectiveDate() == null) {
                        logger.error(price.getId() + ", " + price.getEffectiveDate());
                        continue;
                    }

                    if (price.getEffectiveDate().getTime() != priceDto.getEffectiveDate().getTime()) {
                        logger.error(price.getEffectiveDate() + ", " + priceDto.getEffectiveDate());
                        continue;
                    }

                    logger.info(price.getCurrency() + ", " + priceDto.getCurrency());
                    if (!price.getCurrency().equalsIgnoreCase(priceDto.getCurrency())) {
                        continue;
                    }

                    logger.info(price.getMealCount() + ", " + priceDto.getMealCount());
                    if (price.getMealCount() != priceDto.getMealCount()) {
                        continue;
                    }

                    logger.info(price.getMealType() + ", " + priceDto.getMealType());
                    // 参数数量为0，则不需要管餐食类型；如果不为零，则需要比较餐食类型
                    if (price.getMealCount() == 0 || price.getMealType() == priceDto.getMealType()) {
                        price.setSupplierInclusiveAmount(priceDto.getInclusiveAmount());
                        changeCount++;
                        break;
                    }
                }
            }
        }
        if (changeCount > 0 && changeCount == o.getPrices().size()) {
            hotelOrderDao.updateHotelOrderPrice(enterpriseId, agentName, o.getId(), o.getPrices());
        }

    }

    @Override
    public void checkHotelOrderMeetPolicy(final int enterpriseId, final String username) {
        List<HotelOrder> hotelOrders = hotelOrderDao.searchMeetPolicyHotelOrders(enterpriseId);

        for(HotelOrder o: hotelOrders) {
            if (o.getCustomer() == null) {
                //散客订单
                continue;
            }
            final int customerId = o.getCustomer().getId();
            //1、获取入住人的职位级别，如果有多个，则取最小的一个
            int positionLevel = 0;
            for(HotelOrderPassenger psg: o.getPassengers()) {
                int curPositionLevel = doGetPassengerPositionLevel(enterpriseId, customerId, psg.getName(), psg.getIdType(), psg.getIdNo());
                if (curPositionLevel > 0) {
                    if (positionLevel == 0 || positionLevel > curPositionLevel) {
                        positionLevel = curPositionLevel;
                    }
                }
            }

            if (positionLevel < 1) {
                //未找到该员工的职位级别，无法判断
                hotelOrderDao.updateHotelOrderViolationStatus(enterpriseId, username, o.getId(), 0, "无相关员工职级资料");
                continue;
            }

            final int positionId = positionLevel;
            //TODO 确定酒店所在城市所属的地区分类，未找到分类的，就算三类或其它地区
            //根据酒店ID，查找所属城市
            final int cityId = o.getCityId() == null ? 0 : o.getCityId();
            if (cityId == 0) {
                logger.error("cityId is " + cityId);
                continue;
            }
            CustomerTravelZone travelZone = customerDao.getTravelZoneByCityId(enterpriseId, customerId, cityId);
            final int travelZoneId = travelZone == null ? TRAVEL_ZONE_THIRD_CLASS : travelZone.getTravelZoneId();

            //查找酒店差旅政策
            List<CustomerTpHotel> tps = customerDao.searchCustomerTpHotels(enterpriseId, customerId);
            tps = tps.stream()
                    .filter(t -> t.getCustomerPosition().getPositionId() == positionId)
                    .filter(t -> t.getZoneId() == travelZoneId)
                    .collect(Collectors.toList());
            if (tps.size() == 0) {
                hotelOrderDao.updateHotelOrderViolationStatus(enterpriseId, username, o.getId(), 0, "未找到员工职级相匹配的差旅政策");
                continue;
            }

            //默认违反，只要符合其中的一条就可以了
            int violationStatus = 1;
            String violationReason = null;
            for(CustomerTpHotel tpHotel: tps) {
                if (tpHotel.getMaxReimbursement() == 0) {
                    //实报实销
                    violationStatus = 0;
                    violationReason = "符合差旅政策(" + tpHotel + ")";
                    break;
                }

                if (tpHotel.getMaxReimbursement() >= o.getPrice()) {
                    //每晚均价 符合报销最大值的要求
                    violationStatus = 0;
                    violationReason = "符合差旅政策(" + tpHotel + ")";
                    break;
                }

                //TODO 还需要考虑一人一间/还是两人一间的问题
            }

            //TODO 应该说明符合或违法了那条政策
            hotelOrderDao.updateHotelOrderViolationStatus(enterpriseId, username, o.getId(), violationStatus, violationReason);
        }
    }

    @Override
    public void checkHotelOrderCityId(int enterpriseId, String username) {
        List<HotelOrder> hotelOrders = hotelOrderDao.checkHotelOrderCityIdIsNull(enterpriseId);
        for(HotelOrder o: hotelOrders) {
            if (o.getCityId() == null) {
                CityDto cityDto = doGetCityIdByHotelId(o.getHotelId());
                if (cityDto != null && cityDto.getId() > 0) {
                    hotelOrderDao.updateHotelOrderCityInfo(enterpriseId, username, o.getId(), cityDto.getId(), cityDto.getCityName());
                }
            }
            if (o.getHotelAddress() == null) {
               HotelInfoDto hotelInfoDto = doGetHotelInfoByHotelId(o.getHotelId());
               if (hotelInfoDto != null && hotelInfoDto.getId() == o.getHotelId()) {
                   hotelOrderDao.updateHotelOrderHotelAddress(enterpriseId, username, o.getId(), hotelInfoDto.getAddress());
               }
            }
        }
    }

  @Override
  public JsonResult updateHotelOrderChannel(int enterpriseId, String username, int orderId, int channel) {
    int retCode = hotelOrderDao.updateHotelOrderChannel(enterpriseId, username, orderId, channel);

    return JsonResult.createJsonResult(retCode);
  }

    /**
     * 自动取消“待提交”状态的酒店订单
     * @param enterpriseId 企业id, 必须是自然数（不包括0）
     */
  @Override
  public void checkHotelOrderStatus(final int enterpriseId, final String agentName) {
      if (enterpriseId < 1) {
          return;
      }
      List<HotelOrder> hotelOrders = hotelOrderDao.searchHotelOrderByStatus(enterpriseId, TmsOrderConstant.HOTEL_ORDER_STATUS_WAITING, 100);

      if (hotelOrders.size() == 0) {
          hotelOrders = hotelOrderDao.searchHotelOrderByStatus(enterpriseId, TmsOrderConstant.HOTEL_ORDER_STATUS_SUBMITTED, 100);
      }

      if (hotelOrders.size() == 0) {
          hotelOrders = hotelOrderDao.searchHotelOrderByStatus(enterpriseId, TmsOrderConstant.HOTEL_ORDER_STATUS_PROCESSING, 100);
      }

      for (HotelOrder hotelOrder : hotelOrders) {
          String op1 = hotelOrder.getOperator();
          User user = userDao.getUserByUsername(op1);
          if (user.getParentEnterprise() != enterpriseId) {
              //非企业客户的员工自助下单的，暂时不纳入自动取消操作
//        logger.error(user.getParentEnterprise() + " != " + enterpriseId);
              continue;
          }

          if (hotelOrder.getCheckOutDate().getTime() < DateUtil.getCurDate().getTime()) {
              //离店日期已经早于当日了，该订单肯定无效了。
              hotelOrderDao.cancelHotelOrder(enterpriseId, agentName, hotelOrder.getId(), "离店日期已经过了");
          } else if (hotelOrder.getStatus() == TmsOrderConstant.HOTEL_ORDER_STATUS_WAITING
                  && hotelOrder.getCreateTime() != null
                  && DateUtil.getPastHours(hotelOrder.getCreateTime()) >= 24) {
              //订单已创建24小时了，还没有处理
              hotelOrderDao.cancelHotelOrder(enterpriseId, agentName, hotelOrder.getId(), "订单超过24小时未处理");
          }
      }
  }

    /**
     * 检查是否有新的酒店订单（客户自助下单）需要通知相关业务员
     */
  @Override
  public void checkHotelOrderNotifyStatus(final int enterpriseId, final String username) {
      List<HotelOrder> hotelOrders = hotelOrderDao.searchHotelOrderByStatus(enterpriseId, TmsOrderConstant.HOTEL_ORDER_STATUS_WAITING, 100);

      final Date today = DateUtil.getCurDate();
      for(HotelOrder hotelOrder: hotelOrders) {
          if (hotelOrder.getCreateTime().getTime() < today.getTime()) {
              //创建时间为前一天的，不发送提醒通知
              continue;
          }

          if (hotelOrder.getNotifyStatus() != null) {
                //已经通知了
              continue;
          }

          String op1 = hotelOrder.getOperator();
          User user = userDao.getUserByUsername(op1);
          if (user.getParentEnterprise() != enterpriseId) {
              //非企业客户的员工自助下单的，不处理
//              logger.warn(user.getParentEnterprise() + ", " + enterpriseId);
              continue;
          }

          //发送通知提醒业务员
          String content = "有新的酒店订单了, 订单号：" + hotelOrder.getOrderNo() + ", 客户：" + user.getUsername() + ".";
          doSendAlert(enterpriseId, content, null, EntDepartment.DEPT_CUSTOMER_SERVICE);

          hotelOrderDao.updateHotelOrderNotifyStatus(enterpriseId, username, hotelOrder.getId(), content);
      }

  }

  /**
     * 为机票订单指定审批人
     */
    private void assignApproverHotelOrder(final int enterpriseId, final String username, final int orderId,
                                          final String approver) {
        //TODO 发送短信或邮件提醒该审批人
        int retCode = hotelOrderDao.updateHotelOrderApprover(enterpriseId, username, orderId, approver);
        if (retCode > 0) {
            //发送通知给指定的审批人
        }
    }
}
